Repository Public MIT
1import type { Metadata } from "next";2import Link from "next/link";3import { notFound } from "next/navigation";4import { ArtifactGrid, EmptyState } from "@/components/artifact-card";5import { t } from "@/lib/i18n";6import { publicCtx } from "@/lib/session";7import { getCollection } from "@/server/community";8import { ApiError } from "@/server/errors";910type P = { params: Promise<{ slug: string }> };11async function load(slug: string) {12 try {13 return await getCollection(await publicCtx(), slug);14 } catch (e) {15 if (e instanceof ApiError && e.status === 404) notFound();16 throw e;17 }18}19export async function generateMetadata({ params }: P): Promise<Metadata> {20 const c = await load((await params).slug);21 return { title: `${c.title} — collection`, description: c.description };22}23export default async function Page({ params }: P) {24 const c = await load((await params).slug);25 return (26 <div className="container-page pb-10 pt-12">27 <nav aria-label="Breadcrumb" className="mb-5 font-mono text-[12px] text-faint"><Link href="/collections" className="hover:text-muted">collections</Link> / {c.slug}</nav>28 <header className="mb-8 max-w-3xl">29 <h1 className="text-3xl font-semibold tracking-tight sm:text-4xl">{c.title}</h1>30 <p className="mt-3 text-muted">{c.description}</p>31 </header>32 {c.items.length === 0 ? <EmptyState title={t.empty.collection}>Publishers can suggest an artifact through the <Link className="link" href="/contact">contact page</Link>.</EmptyState> : <ArtifactGrid items={c.items} />}33 </div>34 );35}36